/*******************************************************************************
 * Авторское право (c) 2002, 2013 принадлежит Innoopract Informationssysteme GmbH
 * и другим компаниям.
 * Проект RAP 3.27.0. Оригинальный файл (лицензия EPL v1.0):
 * org.eclipse.rap.rwt.internal.service.ServiceContext.java
 ******************************************************************************/
package erwiki.api.rwc.context.internal.service;

import java.util.Stack;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.elwiki_data.WikiPage;

import erwiki.api.core.Command;
import erwiki.api.core.Engine;
import erwiki.api.core.WikiSession;

/**
 * Инкапсулирует доступ к текущему обрабатываемому запросу, ответу и другой информации о
 * состоянии.</br>
 * По истечении жизненного цикла запроса, соответствующий {@link ServiceContextW} будет удален и при
 * доступе будет выдано IllegalStateException.
 */
public final class ServiceContextW {

	private final Engine engine;
	private HttpServletRequest request;
	private HttpServletResponse response;
	private boolean disposed = false;
	private WikiSession wikiSession;

	private Command command;
	private WikiPage page;
	private int pageVersion;

	Stack<Command> stackCommands = new Stack<>();

	public ServiceContextW(Engine engine, WikiSession wikiSessison, HttpServletRequest request,
			HttpServletResponse response) {
		super();
		this.engine = engine;
		this.wikiSession = wikiSessison;
		this.request = request;
		this.response = response;
	}

	public Engine getEngine() {
		return engine;
	}

	public HttpServletRequest getRequest() {
		checkState();
		return request;
	}

	public HttpServletResponse getResponse() {
		checkState();
		return response;
	}

	public WikiSession getWikiSession() {
		checkState();
		/* TODO: в RAP UISession - был флаг связи, isBound(). Нужен ли такой флаг для WikiSesion?
		if (wikiSession != null && !wikiSession.isBound()) {
			wikiSession = null;
		}*/
		return wikiSession;
	}

	public WikiPage getPage() {
		return this.page;
	}

	public void setPage(WikiPage page) {
		this.page = page;
	}

	public int getPageVersion() {
		return this.pageVersion;
	}

	public void setPageVersion(int pageVersion) {
		this.pageVersion = pageVersion;
	}

	public Command getCommand() {
		return this.command;
	}

	public void setCommand(Command command) {
		this.command = command;
	}

	public void dispose() {
		checkState();
		request = null;
		response = null;
		wikiSession = null;
		/*:FVK: 
		  serviceStore = null;
		  applicationContext = null;
		  */
		disposed = true;
	}

	public boolean isDisposed() {
		return disposed;
	}

	private void checkState() {
		if (disposed) {
			throw new IllegalStateException("The context has been disposed.");
		}
	}

	public void pushCommand() {
		stackCommands.push(getCommand());
	}

	public void popCommand() {
		Command prevCommand = stackCommands.pop();
		setCommand(prevCommand);
	}

}
